package com.mdd.common.config.map;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.map.MapClientConfig;
import com.github.xiaoymin.map.ext.AmapAbstractClient;
import com.github.xiaoymin.map.model.AmapKey;
import com.github.xiaoymin.map.model.MapLocation;
import com.github.xiaoymin.map.request.tencent.AmapCoordTranslateRequest;
import com.github.xiaoymin.map.request.tencent.AmapGenCoderRequest;
import com.github.xiaoymin.map.response.amap.tencent.AmapGenCoderResponse;
import com.github.xiaoymin.map.response.amap.tencent.AmapIpLocationResponse;
import com.github.xiaoymin.map.response.amap.tencent.AmapTenCentDistrictResponse;
import com.github.xiaoymin.map.util.GsonUtils;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.mdd.common.entity.system.SystemConfig;
import com.mdd.common.mapper.system.SystemConfigMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class LikeTenCentClient extends AmapAbstractClient {
    Logger logger = LoggerFactory.getLogger(com.github.xiaoymin.map.ext.TenCentClient.class);

    @Resource
    private SystemConfigMapper systemConfigMapper;

    protected LikeTenCentClient(MapClientConfig mapClientConfig) {
        super(mapClientConfig);
    }

    public Optional<AmapGenCoderResponse> genCoder(AmapGenCoderRequest amapGenCoderRequest) {
        this.assertNotEmpty(amapGenCoderRequest, "逆地理编码API请求对象不能为空");
        String tenCentAmapKey = getMapConfig().getTenCentAmapKey();
        AmapKey amapKey = new AmapKey(tenCentAmapKey, false, (String) null);
        System.out.println(amapKey);
        String api = "https://apis.map.qq.com/ws/geocoder/v1/?" + this.parameter(this.appendKey(amapGenCoderRequest.toMap(), amapKey), amapKey);
        this.logger.info("逆地理编码API:{}", api);
        HttpGet get = new HttpGet(api);
        JsonObject jsonObject = this.responseSuccess(get);
        if (jsonObject != null) {
            JsonObject result = GsonUtils.getJsonObj(jsonObject, "result");
            GsonBuilder gsonBuilder = new GsonBuilder();
            AmapGenCoderResponse amapGenCoderResponse = (AmapGenCoderResponse) gsonBuilder.create().fromJson(result, AmapGenCoderResponse.class);
            return Optional.ofNullable(amapGenCoderResponse);
        } else {
            return Optional.empty();
        }
    }

    public List<MapLocation> getCoordConvert(AmapCoordTranslateRequest amapCoordTranslateRequest) {
        this.assertNotEmpty(amapCoordTranslateRequest, "坐标转换参数不能为空");
        String tenCentAmapKey = getMapConfig().getTenCentAmapKey();
        AmapKey amapKey = new AmapKey(tenCentAmapKey, false, (String) null);
        String api = "https://apis.map.qq.com/ws/coord/v1/translate?" + this.parameter(this.appendKey(amapCoordTranslateRequest.toMap(), amapKey), amapKey);
        this.logger.info("坐标转换API:{}", api);
        HttpGet get = new HttpGet(api);
        JsonObject jsonObject = this.responseSuccess(get);
        if (jsonObject != null) {
            JsonElement locations = jsonObject.get("locations");
            GsonBuilder gsonBuilder = new GsonBuilder();
            List mapLocations = gsonBuilder.create().fromJson(locations, (new TypeToken<List<MapLocation>>() {
            }).getType());
            if (CollectionUtil.isNotEmpty(mapLocations)) {
                return mapLocations;
            }
        }

        return null;
    }

    public Optional<AmapIpLocationResponse> ipLocation(String ip) {
        String tenCentAmapKey = getMapConfig().getTenCentAmapKey();
        AmapKey amapKey = new AmapKey(tenCentAmapKey, false, (String) null);
        Map<String, String> params = MapUtil.builder("ip", ip).build();
        String api = "https://apis.map.qq.com/ws/location/v1/ip?" + this.parameter(this.appendKey(params, amapKey), amapKey);
        this.logger.debug("IP地理位置定位API:{}", api);
        HttpGet get = new HttpGet(api);
        JsonObject jsonObject = this.responseSuccess(get);
        if (jsonObject != null) {
            JsonElement result = jsonObject.get("result");
            GsonBuilder gsonBuilder = new GsonBuilder();
            AmapIpLocationResponse amapIpLocationResponse = (AmapIpLocationResponse) gsonBuilder.create().fromJson(result, AmapIpLocationResponse.class);
            return Optional.ofNullable(amapIpLocationResponse);
        } else {
            return Optional.empty();
        }
    }

    public List<AmapTenCentDistrictResponse> keyWordAddress(String keyword) {
        String tenCentAmapKey = getMapConfig().getTenCentAmapKey();
        AmapKey amapKey = new AmapKey(tenCentAmapKey, false, (String) null);
        Map<String, String> params = MapUtil.builder("keyword", keyword).build();
        String api = "https://apis.map.qq.com/ws/district/v1/search?" + this.parameter(this.appendKey(params, amapKey), amapKey);
        this.logger.debug("获取行政区API:{}", api);
        HttpGet get = new HttpGet(api);
        JsonObject jsonObject = this.responseSuccess(get);
        if (jsonObject != null) {
            JsonElement result = jsonObject.get("result");
            String s = result.toString();
            String substring = s.substring(1, s.length() - 1);
            GsonBuilder gsonBuilder = new GsonBuilder();
            List amapDistrictResponses = gsonBuilder.create().fromJson(substring, (new TypeToken<List<AmapTenCentDistrictResponse>>() {
            }).getType());
            if (CollectionUtil.isNotEmpty(amapDistrictResponses)) {
                return amapDistrictResponses;
            }
        }

        return null;
    }

    public MapLocation address(String keyword) {
        String tenCentAmapKey = getMapConfig().getTenCentAmapKey();
        AmapKey amapKey = new AmapKey(tenCentAmapKey, false, (String) null);
        Map<String, String> params = MapUtil.builder("keyword", keyword).build();
        String api = "https://apis.map.qq.com/ws/geocoder/v1/?address=?" + this.parameter(this.appendKey(params, amapKey), amapKey);
        this.logger.debug("获取行政区API:{}", api);
        HttpGet get = new HttpGet(api);
        JsonObject jsonObject = this.responseSuccess(get);
        if (jsonObject != null) {
            JsonElement result = jsonObject.get("result");
            String s = result.toString();
            GsonBuilder gsonBuilder = new GsonBuilder();
            AmapTenCentDistrictResponse amapDistrictResponses = gsonBuilder.create().fromJson(s, AmapTenCentDistrictResponse.class);
            if (amapDistrictResponses != null) {
                return amapDistrictResponses.getMapLocation();
            }
            return null;
        }

        return null;
    }

    protected JsonObject responseSuccess(HttpUriRequest httpRequest) {
        String content = this.execute(httpRequest);
        if (StrUtil.isNotBlank(content)) {
            JsonElement jsonElement = this.jsonParser.parse(content);
            if (jsonElement != null && jsonElement.isJsonObject() && jsonElement.getAsJsonObject() != null) {
                JsonObject jsonObject = jsonElement.getAsJsonObject();
                String status = GsonUtils.getString(jsonObject, "status");
                if (StrUtil.equals(status, "0")) {
                    return jsonObject;
                }

                this.logger.error("<==============腾讯地图请求接口失败==============>");
            }
        }

        return null;
    }

    /**
     * author woye
     * @return 返回地图配置
     */
    private MapClientConfig getMapConfig(){
        SystemConfig config = systemConfigMapper.selectByTypeAndName("website_map_key", "tencent_map_key");
        MapClientConfig mapClientConfig = new MapClientConfig();
        if (config != null) {
            String key = config.getValue();
            // 腾讯地图配置
            if (StringUtils.isNotEmpty(key)) {
                mapClientConfig.keysTencentMap(key);
            }
        }
        return mapClientConfig;
    }
}
